package com.soho.helper;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import online.mtapi.mt4.Timeframe;

public class StatusHelper {


	//https://docs.mql4.com/constants/chartconstants/enum_timeframes
	public static Timeframe getFrame(int timeFrameValue) {
		switch(timeFrameValue) {
			case 1:return Timeframe.M1;
			case 5:return Timeframe.M5;
			case 15:return Timeframe.M15;
			case 30:return Timeframe.M30;
			case 60:return Timeframe.H1;
			case 240:return Timeframe.H4;
			case 1440:return Timeframe.D1;
			case 10080:return Timeframe.W1;
			case 43200:return Timeframe.MN1;
		}
		return Timeframe.forValue(timeFrameValue);
	}
	
	public static enum TimeFrameEnum {
	    M1(1),M5(5),M15(15),M30(30),H1(60),H4(240),D1(1440),W1(10080),MN1(43200);

	    private long text;

		TimeFrameEnum(long text) {
	        this.text = text;
	    }

	    public long getText() {
	        return this.text;
	    }

	    public static TimeFrameEnum fromString(long text) {
	        for (TimeFrameEnum b : TimeFrameEnum.values()) {
	            if (b.text == text) {
	                return b;
	            }
	        }
	        return null;
	    }
	}
	
	public static String getTableFromTimeFrame(int timeFrameValue) {
		switch(timeFrameValue) {
			case 1:return ContentHelper.TABLE_QUOTES_M1;
			case 5:return ContentHelper.TABLE_QUOTES_M5;
			case 15:return ContentHelper.TABLE_QUOTES_M15;
			case 30:return ContentHelper.TABLE_QUOTES_M30;
			case 60:return ContentHelper.TABLE_QUOTES_H1;
			case 240:return ContentHelper.TABLE_QUOTES_H4;
			case 1440:return ContentHelper.TABLE_QUOTES_D1;
			case 10080:return ContentHelper.TABLE_QUOTES_W;
			case 43200:return ContentHelper.TABLE_QUOTES_MN;
		}	
		return "";
	}
	
	/**
	 * M1,M5,M15,M30,H1,H4,D1,W,MN
	 */
	public static String getM1(LocalDateTime localDateTime) {
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm"));
	}
	
	public static String getM5(LocalDateTime localDateTime) {
		int minute 			=	localDateTime.getMinute();
		String minuteStr	=	"";
		if(minute<=5) {
			minuteStr		=	"00";
		}else if(minute<=10) {
			minuteStr		=	"05";
		}else if(minute<=15) {
			minuteStr		=	"10";
		}else if(minute<=20) {
			minuteStr		=	"15";
		}else if(minute<=25) {
			minuteStr		=	"20";
		}else if(minute<=30) {
			minuteStr		=	"25";
		}else if(minute<=35) {
			minuteStr		=	"30";
		}else if(minute<=40) {
			minuteStr		=	"35";
		}else if(minute<=45) {
			minuteStr		=	"40";
		}else if(minute<=50) {
			minuteStr		=	"45";
		}else if(minute<=55) {
			minuteStr		=	"50";
		}else {
			minuteStr		=	"55";
		}
		
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:"))+minuteStr;
	}

	public static String getM15(LocalDateTime localDateTime) {
		int minute 			=	localDateTime.getMinute();
		String minuteStr	=	"";
		if(minute<=15) {
			minuteStr		=	"00";
		}else if(minute<=30) {
			minuteStr		=	"15";
		}else if(minute<=45) {
			minuteStr		=	"30";
		}else{
			minuteStr		=	"45";
		}
		
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:"))+minuteStr;
	}

	public static String getM30(LocalDateTime localDateTime) {
		int minute 			=	localDateTime.getMinute();
		String minuteStr	=	"";
		if(minute<=30) {
			minuteStr		=	"00";
		}else{
			minuteStr		=	"30";
		}
		
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:"))+minuteStr;
	}
	
	public static String getH1(LocalDateTime localDateTime) {
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd HH:00"));
	}
	
	public static String getH4(LocalDateTime localDateTime) {
		int hour 			=	localDateTime.getHour();
		String hourStr 		=	"";
		if(hour<=4) {
			hourStr			=	"00:00";
		}else if(hour<=8) {
			hourStr			=	"04:00";
		}else if(hour<=12) {
			hourStr			=	"08:00";
		}else if(hour<=16) {
			hourStr			=	"12:00";
		}else if(hour<=20) {
			hourStr			=	"16:00";
		}else{
			hourStr			=	"20:00";
		}
		
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd "))+hourStr;
	}
	
	public static String getD1(LocalDateTime localDateTime) {
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd 00:00"));
	}

	private static Map<String,String> weekCacheList = new ConcurrentHashMap<>();
	
	public static String getW(LocalDateTime localDateTime,String symbole) {
		int currDay		=	localDateTime.getDayOfMonth();
		int currMonth	=	localDateTime.getMonthValue();
		int currDayInY	=	localDateTime.getDayOfYear();
		
		String cacheKey	=	symbole+"_"+currDayInY;
		if(weekCacheList.containsKey(cacheKey)) {
			return weekCacheList.get(cacheKey);
		}
		
		
		long lastTime	=	SqlHelper.getLastTime(symbole, ContentHelper.TABLE_QUOTES_W,0);
		int useDay		=	0;
		//不存在
		if(lastTime==0) {
			//不存在就尴尬了,就以今天为开始了?,所以前提一定要初始化好数据
			useDay		=	currDay;
		}else {
			//如果数据库有值的话,则进行判断
			LocalDateTime dbTime	=	LocalDateTime.ofInstant(Instant.ofEpochSecond(lastTime),ZoneId.systemDefault());
			int dbDay				=	dbTime.getDayOfMonth();
			
			//下一周的边界
			LocalDateTime nextTime	=	dbTime.plusDays(7);
			int nextWeekDay			=	nextTime.getDayOfMonth();
			int nextMonth			=	nextTime.getMonthValue();
			
			//如果是本月,且时间少于今天,则说明已过期,eg: nextWeekDay=10.20, currDay=10.28
			if(nextMonth==currMonth) {
				if(nextWeekDay<=currDay) {
					// nextWeekDay=10.20, currDay=10.20
					if(nextWeekDay == currDay) {
						useDay			=	currDay;
					}else {
						// nextWeekDay=10.20, currDay=10.28 -> 10.20+7=10.27 < 10.28,so nextWeekDay=10.27
						while(nextWeekDay<=currDay) {
							if(nextTime.plusDays(7).getDayOfYear()<=currDayInY) {
								nextTime	=	nextTime.plusDays(7);
								nextWeekDay	=	nextTime.getDayOfMonth();
							}else {
								break;
							}
						}
						useDay			=	nextTime.getDayOfMonth();
					}
				}else {
					//nextWeekDay=10.28, currDay=10.27,则还是使用原数据库的
					useDay				=	dbDay;
				}
			}else {
				//这是跨月的情况.goad,nextMonth=10,currMonth=11,这是什么情况
				if(nextMonth<currMonth) {
					while(nextTime.plusDays(7).getDayOfYear()<=currDayInY) {
						nextTime		=	nextTime.plusDays(7);
					}
					useDay				=	nextTime.getDayOfMonth();
				}else {
					//eg: currMonth=10.27,nextMonth=11.2 这是什么情况
					useDay				=	dbDay;
				}
			}
		}
		
		String wStr		=	useDay<10?"0"+useDay+" 00:00":useDay+" 00:00";
		String weekDay	=	 localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM."))+wStr;
		weekCacheList.put(cacheKey, weekDay);
		return weekDay;
	}

	public static String getMN(LocalDateTime localDateTime) {
		return localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.01 00:00"));
	}
	
	/**
	 * 通过接口测试得到下面的数据
		M1 		-1
		M5      -5
		M15     -15
		M30     -30
		H1      -1 HOUR
		H4      -4 HOUR
		D1      -1 DAY
		W1      -1 WEEK
		WN      -1 MONTH
	 */
	public static String getSearchTimeFromFrame(LocalDateTime localDateTime,int timeFrameValue,String symbole) {
		switch(timeFrameValue) {
			case 1:
				return getPreTime(getM1(localDateTime), timeFrameValue);
			case 5:
				return getPreTime(getM5(localDateTime), timeFrameValue);
			case 15:
				return getPreTime(getM15(localDateTime), timeFrameValue);
			case 30:
				return getPreTime(getM30(localDateTime), timeFrameValue);
			case 60:
				return getPreTime(getH1(localDateTime), timeFrameValue);
			case 240:
				return getPreTime(getH4(localDateTime), timeFrameValue);
			case 1440:
				return getPreTime(getD1(localDateTime), timeFrameValue);
			case 10080:
				return getPreTime(getW(localDateTime,symbole), timeFrameValue);
			case 43200:
				return getPreTime(getMN(localDateTime), timeFrameValue);
		}	
		return "";
	}
	
	public static String getPreTime(String nowTime,int timeFrameValue) {
		LocalDateTime currTime	=	LocalDateTime.ofInstant(Instant.ofEpochSecond(TimeHelper.getSecondFromStr(nowTime)), ZoneId.systemDefault());;
		switch(timeFrameValue) {
		case 1:
			return TimeHelper.formatLocalDateTime(currTime.minusMinutes(1));
		case 5:
			return TimeHelper.formatLocalDateTime(currTime.minusMinutes(5));
		case 15:
			return TimeHelper.formatLocalDateTime(currTime.minusMinutes(15));
		case 30:
			return TimeHelper.formatLocalDateTime(currTime.minusMinutes(30));
		case 60:
			return TimeHelper.formatLocalDateTime(currTime.minusHours(1));
		case 240:
			return TimeHelper.formatLocalDateTime(currTime.minusHours(4));
		case 1440:
			return TimeHelper.formatLocalDateTime(currTime.minusDays(1));
		case 10080:
			return TimeHelper.formatLocalDateTime(currTime.minusWeeks(1));
		case 43200:
			return TimeHelper.formatLocalDateTime(currTime.minusMonths(1));
		}	
		return "";
	}
	
	//获取减免的分数？远程服务器有10.25的数据，通过接口只能拉到10.24的数据,so,当前时间往前减一格了，比如如果是5分钟的话，就减5
//	public static String getPreTime(String fromTime) {
//		
//	}
}
